package net.minecraft.client.model;

import java.util.List;
import java.util.function.Function;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;

/**
 * Represents a dynamic model which has its own render layers and custom rendering.
 */
@Environment(EnvType.CLIENT)
public abstract class Model {
	protected final ModelPart root;
	protected final Function<Identifier, RenderLayer> layerFactory;
	private final List<ModelPart> parts;

	public Model(ModelPart root, Function<Identifier, RenderLayer> layerFactory) {
		this.root = root;
		this.layerFactory = layerFactory;
		this.parts = root.traverse();
	}

	/**
	 * {@return the render layer for the corresponding texture}
	 * 
	 * @param texture the texture used for the render layer
	 */
	public final RenderLayer getLayer(Identifier texture) {
		return (RenderLayer)this.layerFactory.apply(texture);
	}

	public final void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, int color) {
		this.getRootPart().render(matrices, vertices, light, overlay, color);
	}

	public final void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay) {
		this.render(matrices, vertices, light, overlay, -1);
	}

	public final ModelPart getRootPart() {
		return this.root;
	}

	public final List<ModelPart> getParts() {
		return this.parts;
	}

	public final void resetTransforms() {
		for (ModelPart modelPart : this.parts) {
			modelPart.resetTransform();
		}
	}

	@Environment(EnvType.CLIENT)
	public static class SinglePartModel extends Model {
		public SinglePartModel(ModelPart part, Function<Identifier, RenderLayer> layerFactory) {
			super(part, layerFactory);
		}
	}
}
